package com.xyoto.community.service.impl;

import com.github.pagehelper.PageHelper;
import com.xyoto.community.constant.*;
import com.xyoto.community.dto.PageDTO;
import com.xyoto.community.dto.SaveQuestionDTO;
import com.xyoto.community.entity.main.Message;
import com.xyoto.community.entity.main.Question;
import com.xyoto.community.enums.*;
import com.xyoto.community.exception.ExceptionUtils;
import com.xyoto.community.mapper.comment.QuestionCommentMapper;
import com.xyoto.community.mapper.comment.QuestionCommentReplyMapper;
import com.xyoto.community.mapper.main.MessageMapper;
import com.xyoto.community.mapper.main.QuestionMapper;
import com.xyoto.community.mapper.main.TopicMapper;
import com.xyoto.community.mapper.main.UserMapper;
import com.xyoto.community.po.UserPO;
import com.xyoto.community.service.QuestionService;
import com.xyoto.community.service.TopicService;
import com.xyoto.community.service.UserService;
import com.xyoto.community.utils.JwtUtils;
import com.xyoto.community.utils.PageUtils;
import com.xyoto.community.utils.Result;
import com.xyoto.community.vo.QuestionDetailsVo;
import com.xyoto.community.vo.QuestionListVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * ClassName:   问答Service接口实现类
 * Author:      挽风
 * Date:        2020
 * Copyright:   2020 by 挽风1.0版本
 * Description:
 **/

//@Service
@Slf4j
public class QuestionServiceImpl implements QuestionService {

    @Autowired
    private UserService userService;

    @Autowired
    
    private TopicService topicService;

    @Resource
    private QuestionMapper questionMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private TopicMapper topicMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private QuestionCommentMapper questionCommentMapper;

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private QuestionCommentReplyMapper questionCommentReplyMapper;


    /**
     * 新增问答
     *
     * @param saveQuestionDTO 问答表单Dto
     *
     * @return 操作状态
     */
    @Override
    public Result saveQuestion(SaveQuestionDTO saveQuestionDTO) {

        // 获取用户id
        Integer userId = JwtUtils.getMemberIdByJwtToken(request);
        if (userId == UserLoginStatus.UN_LOGIN){
            ExceptionUtils.error(WechatLoginEnum.USER_NOT_LOGIN);
        }

        log.info("=====执行新增问答=====");
        // 判断问答所属的话题是否存在
        Integer count = topicService.getTopicIsExistById(saveQuestionDTO.getTopicId());
        if (count != 1){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_TALL_TOPIC_NOT_NULL);
        }

        // 保存问答
        Question question = new Question();
        BeanUtils.copyProperties(saveQuestionDTO,question);
        question.setUserId(userId);

        log.info("=====执行插入问答SQL=====");
        Integer save = questionMapper.saveQuestion(question);
        if (save < DatabaseOperationResult.SUCCESS){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_ADD_ERROR);
        }
        return Result.success();
    }

    /**
     * 根据问答id查询问答详情
     *
     * @param questionId 问答id
     *
     * @return 问答详情
     */
    @Override
    public Result getQuestionDetailsById(Integer questionId) {

        log.info("=====开始查询问答详情=====");
        if (null == questionId || questionId <= 0){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_NULL);
        }

        // 查询问答内容详情
        QuestionDetailsVo questionDetails = new QuestionDetailsVo();
        Question question = questionMapper.getQuestionDetailsById(questionId);
        if (question == null){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_NULL);
        }

        // 获取用户id查询所属用户
        Integer userId = question.getUserId();
        BeanUtils.copyProperties(question, questionDetails);

        // 查询问答所属用户
        UserPO userPo = userService.getUserPartInfoById(userId);
        if (userPo == null){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_NULL);
        }
        BeanUtils.copyProperties(userPo, questionDetails);
        log.info("=====结束查询问答详情=====");
        return Result.success(questionDetails);
    }

    @Override
    public Result<PageUtils<QuestionListVo>> getQuestionListByTime(PageDTO pageDTO, Integer topicId){
        //id不合法
        if(topicId == null || topicId <= 0){
            return new Result(TopicEnum.TOPIC_NOT_EXIST);
        } else {
            //问答所在话题不存在
            Integer status = topicMapper.countTopicIsExistById(topicId , DeleteStatus.NO);

            if(status == 0){
                return new Result(TopicEnum.TOPIC_NOT_EXIST);
            }
        }

        PageHelper.startPage(pageDTO.getPageNum(), pageDTO.getPageSize());
        List<QuestionListVo> questionListVos = questionMapper.getQuestionListByTime(pageDTO.getEndIndexId(),topicId, DeleteStatus.NO);

        for(QuestionListVo questionListVo:questionListVos){
            UserPO userPO = userMapper.getUserPartInfoById(questionListVo.getUserId());
            questionListVo.setAvatar(userPO.getAvatarUrl());
            questionListVo.setNickname(userPO.getNickname());
            questionListVo.setCommentCount(questionCommentMapper.countQuestionComment(pageDTO.getEndIndexId(),questionListVo.getQuestionId(), DeleteStatus.NO));
        }

        return new Result(CommonEnum.SUCCESS, PageUtils.restPage(questionListVos));

    }

    /**
     * 删除问答
     *
     * @param questionId 问答id
     * @return
     */
    @Override
    public Result removeQuestion(Integer questionId) {
        if (null == questionId || questionId <= 0) {
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_NULL);
        }
        //todo 检验权限 管理员权限未加
        //此条问答主人以及管理员可删此回复，其余用户不可删
        //检验问答是否存在
        Question question = questionMapper.getQuestionById(questionId);
        checkQuestionExist(question);
        //获取问答主人id
        Integer questionUserId = question.getUserId();
        //当前用户id
        Integer userId = JwtUtils.getMemberIdByJwtToken(request);
        if (!userId.equals(questionUserId)) {
            ExceptionUtils.error(QuestionsEnum.NOT_POWER);
        }
        Question newQuestion = new Question();
        newQuestion.setDeleteStatus(DeleteStatus.YES);
        newQuestion.setId(questionId);
        newQuestion.setUserId(userId);
        //删除问答业务操作
        Integer state = questionMapper.removeQuestion(newQuestion);
        if (state != OperationStatus.SUCCESS) {
            ExceptionUtils.error(QuestionsEnum.DELETE_QUESTION_COMMENT_REPLY_FAILED);
        }
        //删除问答评论消息
        List<Integer> questionCommentIdList = questionCommentMapper
                .getQuestionCommentList(questionId);
        if (questionCommentIdList.size() != 0){
            for (Integer questionCommentId : questionCommentIdList){
                Message newMessage = new Message();
                newMessage.setType(ModuleType.QUESTION_COMMENT);
                newMessage.setModuleId(questionCommentId);
                newMessage.setThirdParentId(questionId);
                Integer newStatus = messageMapper.removeMessage(newMessage);
                if (newStatus != OperationStatus.SUCCESS){
                    ExceptionUtils.error(MessageEnum.DELETED_QUESTION_COMMENT_MESSAGE_FAILED);
                }
                //删除问答评论回复消息
                List<Integer> questionCommentReplyIdList = questionCommentReplyMapper
                        .getQuestionCommentReplyListByQuestionCommentId(questionCommentId);
                if (questionCommentReplyIdList.size() != 0){
                    for (Integer questionCommentReplyId : questionCommentReplyIdList){
                        Message m = new Message();
                        m.setThirdParentId(questionId);
                        m.setModuleId(questionCommentReplyId);
                        m.setType(ModuleType.QUESTION_COMMENT_REPLY);
                        Integer status = messageMapper.removeMessage(m);
                        if (status != OperationStatus.SUCCESS){
                            ExceptionUtils.error(MessageEnum.DELETED_QUESTION_COMMENT_REPLY_MESSAGE_FAILED);
                        }
                    }
                }
            }
        }
        return Result.success();
    }

    /**
     * 检查问答是否存在或已经被逻辑删除
     * @param question
     */
    private void checkQuestionExist(Question question) {
        if (null == question){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_NULL);
        }
        if (question.getDeleteStatus().equals(DeleteStatus.YES)){
            ExceptionUtils.error(QuestionsEnum.QUESTIONS_IS_DELETE);
        }
    }
}
